/**
* ===============================================================================================================
* Native driver for lan911x Ethernet Controller.
*
* There has nothing depedency on Operating System or upper layer protocol stack.
* Yeah, it just a pure and clean driver. You can build the TCP/IP stack based on this driver.
* ===============================================================================================================
* Reference
*
* https://ww1.microchip.com/downloads/en/DeviceDoc/00002266B.pdf
* https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/en562758.pdf
*
* ===============================================================================================================
* Copyright (c) 2024, DY Young.
* All rights reserved.
*
* Licencse Term
*----------------
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*    following disclaimer in the documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* ===============================================================================================================
*/

#include "lan911x_native.h"




/** Direct Address Memory Mapped Register  **/
/** -------------------------------------- **/
enum direct_address_register_map {
/** FIFO Port */
    RX_DATA_FIFO    =   0x0,
    RX_DATA_ALIAS   =   0x4,
    TX_DATA_FIFO    =   0x20,
    TX_DATA_ALIAS   =   0x24,
    RX_STATUS_FIFO  =   0x40,
    RX_STATUS_PEEK  =   0x44,
    TX_STATUS_FIFO  =   0x48,
    TX_STATUS_PEEK  =   0x4c,

/** slave CSR */
    ID_REV          =   0x50,      // Chip ID and Revision
    IRQ_CFG         =   0x54,      // Main Interrupt Configuration
    INT_STS         =   0x58,      // Interrupt Status
    INT_EN          =   0x5c,      // Interrupt Enable
// RESERVED         =   0x60,
    BYTE_TEST       =   0x64,      // Ready-only byte order testing
    FIFO_INT        =   0x68,      // FIFO level interrupts
    RX_CFG          =   0x6C,      // Receive Configuration
    TX_CFG          =   0x70,      // Transmit Configuration
    HW_CFG          =   0x74,      // Hardware Configuration
    RX_DP_CTL       =   0x78,      // RX Datapath Control
    RX_FIFO_INF     =   0x7c,      // RX FIFO Information
    TX_FIFO_INF     =   0x80,      // TX FIFO Information
    PMT_CTRL        =   0x84,      // Power Management Control
    GPIO_CFG        =   0x88,      // GPIO Configuration
    GPT_CFG         =   0x8c,      // General Purpose Timer Configuration
    GPT_CNT         =   0x90,      // GP Timer Count
// RESERVED         =   0x94,
    WORD_SWAP       =   0x98,      // Word swap
    FREE_RUN        =   0x9c,      // Free run


/** MAC CSR */
    RX_DROP         =   0xA0,      // RX Dropped Frames Counter
    MAC_CSR_CMD     =   0xA4,      // MAC CSR Synchronizer Command, to index MAC's CSR
    MAC_CSR_DATA    =   0xA8,      // MAC CSR Synchronizer Data
    AFC_CFG         =   0xAC,      // Automatic Flow Control Configuration

/** EEPROM */  
    E2P_CMD         =   0xB0,      // EEPROM command
    E2P_DATA        =   0xB4,      // EEPROM DATA
};

/* TX Status Format
 * 31-16: packet tag
 * 15   : Error Status
 * 14-12: -
 * 11   : Loss of Carrier
 * 10   : No Carrier
 * 9    : Late Collision
 * 8    : Excessive Collisions
 * 7    : -
 * 6-3  : Collision Count
 * 2    : Excessive Deferral
 * 1    : -
 * 0    : Deferred
 */
U32_FEILD_START(vTX_STATUS)
uint32 useless(0) : 15;
uint32 error      : 1;
uint32 packet_tag : 16;
U32_FEILD_STOP(vTX_STATUS);

/* RX Status Format
 * 30   : Filtering Fail
 * 29-16: Packet Length
 * 15   : Error Status
 * 14   : -
 * 13   : Broadcast Frame
 * 12   : Length Error
 * 11   : Runt Frame
 * 10   : Multicast Frame
 * 9-8  : -
 * 7    : Frame too long
 * 6    : Collision Seen
 * 5    : Frame Type
 * 4    : Receive watchdog timeout
 * 3    : MII Error
 * 2    : Dribbling bit
 * 1    : CRC Error
 * 0    : -
 */
U32_FEILD_START(vRX_STATUS)
uint32 error_reason : 15;
uint32 error        : 1;
uint32 packet_len   : 14;
uint32 filter_fail  : 1;
uint32 useless(0)   : 1;
U32_FEILD_STOP(vRX_STATUS)

/* TX Command A Format
 * 31    : Interrupt on Completion
 * 30-26 : -
 * 25-24 : Buffer End Alignment
 * 23-21 : -
 * 20-16 : Data Start Byte Offset
 * 15-14 : -
 * 13    : First Segment
 * 12    : Last Segment
 * 11    : -
 * 10-0  : Buffer Byte Size
 */
U32_FEILD_START(vTX_CMD_A)
uint32 buff_size  : 11;
uint32 useless(3) : 1;
uint32 last_seg   : 1;
uint32 first_seg  : 1;
uint32 useless(2) : 2;
uint32 start_off  : 5;
uint32 useless(1) : 3;
#define ALIGN_4B    0
#define ALIGN_16B   1
#define ALIGN_32B   2
uint32 end_align  : 2;
uint32 useless(0) : 5;
uint32 int_on_done: 1;
U32_FEILD_STOP(vTX_CMD_A)

/* TX Command B Format
 * 31-16 : unique packet tag
 * 15-14 : -
 * 13    : Add CRC Disable
 * 12    : Disable Ethernet Frame Padding
 * 11    : -
 * 10-0  : Packet Byte Length
 */
U32_FEILD_START(vTX_CMD_B)
uint32 pack_len     : 11;
uint32 useless(1)   : 1;
uint32 dis_pad      : 1;
uint32 crc_dis      : 1;
uint32 useless(0)   : 2;
uint32 pack_tag     : 16;
U32_FEILD_STOP(vTX_CMD_B)


/**
 * ID_REV format 5.3.1
 * 31-16 : Chip ID
 * 15-0  : Chip Revision
 */
U32_FEILD_START(vID_REV)
uint32 revision : 16;
uint32 chipid   : 16;
U32_FEILD_STOP(vID_REV)

/**
 * IRQ_CFG format 5.3.2
 * 31-24 : Interrupt Deassertion Interval
 * 23-15 : -
 * 14    : Interrupt Deassertion Interval Clear
 * 13    : Interrupt Deassertion Status
 * 12    : Master Interrupt
 * 11-9  : -
 * 8     : IRQ Enable
 * 7-5   : -
 * 4     : IRQ Polarity
 * 3-1   : -
 * 0     : IRQ Buffer Type
 */
U32_FEILD_START(vIRQ_CFG)
uint32 IRQ_TYPE     : 1;
uint32 useless(0)   : 3;
uint32 IRQ_POL      : 1;
uint32 useless(1)   : 3;
uint32 IRQ_EN       : 1;
uint32 useless(2)   : 3;
uint32 IRQ_INT      : 1;
uint32 IRQ_DEAS_STS : 1;
uint32 IRQ_DEAS_CLR : 1;
uint32 useless(3)   : 9;
uint32 INT_DEAS     : 8;
U32_FEILD_STOP(vIRQ_CFG)


/**
 * INT_STS format 5.3.3
 * 31    : Software Interrupt
 * 30-26 : -
 * 25    : TX Stopped
 * 24    : RX Stopped
 * 23    : RX Dropped Frame Counter Halfway
 * 22    : -
 * 21    : TX IOC Interrupt
 * 20    : RX DMA Interrupt
 * 19    : GP Timmer
 * 18    : PHY
 * 17    : Power Management Event Interrupt
 * 16    : TX Status FIFO Overflow
 * 15    : Receive watchdog timeout
 * 14    : Receiver Error
 * 13    : Transmitter Error
 * 12-11 : -
 * 10    : TX Data FIFO Overrun Interrupt
 * 9     : TX Data FIFO Available Interrupt
 * 8     : TX Status FIFO Full
 * 7     : TX Status FIFO Level
 * 6     : RX Dropped Frame
 * 5     : -
 * 4     : RX Status FIFO Full
 * 3     : RX Status FIFO Level
 * 2-0   : GPIO
 */
U32_FEILD_START(vINT_STS)
uint32 GPIOx_INT  : 3;
uint32 RSFL       : 1;
uint32 RSFF       : 1;
uint32 useless(0) : 1;
uint32 RXDF_INT   : 1;
uint32 TSFL       : 1;
uint32 TSFF       : 1;
uint32 TDFA       : 1;
uint32 TDFO       : 1;
uint32 useless(1) : 2;
uint32 TXE        : 1;
uint32 RXE        : 1;
uint32 RWT        : 1;
uint32 TXSO       : 1;
uint32 PME_INT    : 1;
uint32 PHY_INT    : 1;
uint32 GPT_INT    : 1;
uint32 RXD_INT    : 1;
uint32 TX_IOC     : 1;
uint32 useless(2) : 1;
uint32 RXDFH_INT  : 1;
uint32 RXSTOP_INT : 1;
uint32 TXSTOP_INT : 1;
uint32 useless(3) : 5;
uint32 SW_INT     : 1;
U32_FEILD_STOP(vINT_STS)

/**
 * INT_EN format 5.3.4
 * 31    : Software Interrupt
 * 30-26 : -
 * 25    : TX Stopped
 * 24    : RX Stopped
 * 23    : RX Dropped Frame Counter Halfway
 * 22    : -
 * 21    : TX IOC Interrupt
 * 20    : RX DMA Interrupt
 * 19    : GP Timmer
 * 18    : PHY
 * 17    : Power Management Event Interrupt
 * 16    : TX Status FIFO Overflow
 * 15    : Receive watchdog timeout
 * 14    : Receiver Error
 * 13    : Transmitter Error
 * 12-11 : -
 * 10    : TX Data FIFO Overrun Interrupt
 * 9     : TX Data FIFO Available Interrupt
 * 8     : TX Status FIFO Full
 * 7     : TX Status FIFO Level
 * 6     : RX Dropped Frame
 * 5     : -
 * 4     : RX Status FIFO Full
 * 3     : RX Status FIFO Level
 * 2-0   : GPIO
 */
U32_FEILD_START(vINT_EN) //
uint32 GPIOx_INT  : 3;
uint32 RSFL       : 1;
uint32 RSFF       : 1;
uint32 useless(0) : 1;
uint32 RXDF_INT   : 1;
uint32 TSFL       : 1;
uint32 TSFF       : 1;
uint32 TDFA       : 1;
uint32 TDFO       : 1;
uint32 useless(1) : 2;
uint32 TXE        : 1;
uint32 RXE        : 1;
uint32 RWT        : 1;
uint32 TXSO       : 1;
uint32 PME_INT    : 1;
uint32 PHY_INT    : 1;
uint32 GPT_INT    : 1;
uint32 RXD_INT    : 1;
uint32 TX_IOC     : 1;
uint32 useless(2) : 1;
uint32 RXDFH_INT  : 1;
uint32 RXSTOP_INT : 1;
uint32 TXSTOP_INT : 1;
uint32 useless(3) : 5;
uint32 SW_INT     : 1;
U32_FEILD_STOP(vINT_EN)

/**
 * BYTE_TEST format 5.3.5
 * 31-0 : Byte Test 
 */
U32_FEILD_START(vBYTE_TEST)
uint32 ORDER;
U32_FEILD_STOP(vBYTE_TEST)


/**
 * FIFO_INT format 5.3.6
 * 31-24 : TX Data Available Level
 * 23-16 : TX Status Level
 * 15-8  : -
 * 7-0   : RX Status Level
 */
U32_FEILD_START(vFIFO_INT)
uint32 RX_STATUS_LEVEL : 8;
uint32 useless(0)      : 8;
uint32 TX_STATUS_LEVEL : 8;
uint32 TX_DATA_LEVEL   : 8;
U32_FEILD_STOP(vFIFO_INT)

/* RX_CFG Format 5.3.7
 * 31-30 : RX End Alignment
 * 29-28 : -
 * 27-16 : RX DMA Count
 * 15    : Force RX Discard
 * 14-13 : -
 * 12-8  : Rx Data Offset
 * 7-0   : -
 */
U32_FEILD_START(vRX_CFG)
uint32 useless(0)   : 8;
uint32 RXDOFF       : 5;
uint32 useless(1)   : 2;
uint32 RX_DUMP      : 1;
uint32 RX_DMA_CNT   : 12;
uint32 useless(2)   : 2;
uint32 RX_END_ALIGN : 2;
U32_FEILD_STOP(vRX_CFG)

/* TX_CFG Format 5.3.8
 * 31-16 : -
 * 15    : Force TX Status Discard
 * 14    : Force TX Data Discard
 * 13-3  : -
 * 2     : TX Status Allow Overrun
 * 1     : Transmitter Enable
 * 0     : Stop Transmitter
 */
U32_FEILD_START(vTX_CFG)
uint32 STOP_TX      : 1;
uint32 TX_ON        : 1;
uint32 TXSAO        : 2;
uint32 useless(0)   : 11;
uint32 TX_DUMP      : 1;
uint32 TXS_DUMP     : 1;
uint32 useless(1)   : 16;
U32_FEILD_STOP(vTX_CFG)

/* HW_CFG Format 5.3.9
 * 31-21 : -
 * 20    : Must Be One
 * 19-16 : TX FIFO Size
 * 15-3  : -
 * 2     : 32/16-bit Mode
 * 1     : Soft Reset Timeout
 * 0     : Soft Reset
 */
U32_FEILD_START(vHW_CFG)
uint32 SRST         : 1;
uint32 SRSR_TO      : 1;
uint32 Mode32n16    : 1;
uint32 useless(0)   : 13;
// TX_FIFO + RX_FIFO = 16384B = 16KB
// TX_FIFO = TX_DATA_FIFO  + TX_STATUS_FIFO(512B)
// RX_FIFO = RX_FIFO*15/16 + RX_FIFO*1/16
// RX_FIFO = RX_DATA_FIFO  + RX_STATUS_FIFO
// -----------------------------------------
// TX_FIF_SZ TX_D   TX_S    RX_D    RX_S (B)
// -----------------------------------------
// 2        1536    512     13440   896
// 3        2560    512     12480   832
// 4        3584    512     11520   768
// 5        4608    512     10560   704
// 6        5632    512     9600    640
// 7        6656    512     8640    576
// 8        7680    512     7680    512
// 9        8704    512     6720    448
// 10       9728    512     5760    384
// 11       10752   512     4800    320
// 12       11776   512     3840    256
// 13       12800   512     2880    192
// 14       13824   512     1920    128
uint32 TX_FIF_SZ    : 4;
uint32 MBO          : 1;
uint32 useless(1)   : 11;
U32_FEILD_STOP(vHW_CFG)

/**
 * RX_DP_CTRL Format 5.3.10
 * 31   : RX Data FIFO Fast Forward
 * 30-0 : -
 */
U32_FEILD_START(vRX_DP_CTRL)
uint32 useless(0): 31;
uint32 RX_FFWD   : 1;
U32_FEILD_STOP(vRX_DP_CTRL)

/**
 * RX_FIFO_INF Format 5.3.11
 * 31-24 : -
 * 23-16 : RX Status FIFO Used Space
 * 15-0  : RX Data FIFO Used Space
 */
U32_FEILD_START(vRX_FIFO_INF)
uint32 RXD_USED   : 16;
uint32 RXS_USED   : 8;
uint32 useless(0) : 8;
U32_FEILD_STOP(vRX_FIFO_INF)

/* TX_FIFO_INF Format 5.3.12
 * 31-24: -
 * 23-16: TX Status FIFO Used Space
 * 15-0 : TX Data FIFO Free Space
 */
U32_FEILD_START(vTX_FIFO_INF)
uint32 TXD_FREE   : 16;
uint32 TXS_USED   : 8;
uint32 useless(0) : 8;
U32_FEILD_STOP(vTX_FIFO_INF)

/**
 * PMT_CTRL Format 5.3.13
 * 31-14: -
 * 13-12: Power Management Mode
 * 11   : -
 * 10   : PHY Reset
 * 9    : Wake-ON-Lan enable
 * 8    : Energy Detect Enable
 * 7    : -
 * 6    : PME Buffer Type
 * 5-4  : Wake-up Status
 * 3    : PME Indication
 * 2    : PME Polarity
 * 1    : PME Enable
 * 0    : Device Ready
 */
U32_FEILD_START(vPMT_CTRL)
uint32 ready      : 1;
uint32 PME_EN     : 1;
uint32 PME_POL    : 1;
uint32 PME_IND    : 1;
uint32 WUP_STAT   : 2;
uint32 PME_TYPE   : 1;
uint32 useless(0) : 1;
uint32 ED_EN      : 1;
uint32 WOL_EN     : 1;
uint32 PHY_RST    : 1;
uint32 useless(1) : 1;
#define   D0        0b00
#define   D1        0b01
#define   D2        0b11
uint32 PM_MODE    : 2;
uint32 useless(2) : 18;
U32_FEILD_STOP(vPMT_CTRL)

/**
 * GPIO_CFG Format 5.3.14
 *
 */


/**
 * GPT_CFG Format 5.3.15
 *
 */


/**
 * GPT_CNT Format 5.3.16
 *
 */


/**
 * WORD_SWAP Format 5.3.17
 *
 */


/**
 * FREE_RUN Format 5.3.18
 *
 */


/**
 * RX_DROP_CFG Format 5.3.19
 *
 */


/**
 * MAC_CSR_CMD Format 5.3.20
 * 31   : CSR Busy
 * 30   : Read/nWrite
 * 29-8 : -
 * 7-0  : CSR Address
 */
U32_FEILD_START(vMAC_CSR_CMD)
#define READ_MAC_REG    1
#define WRITE_MAC_REG   0
uint32 reg_index      : 8;
uint32 useless(0)     : 22;
uint32 r_nw           : 1;
uint32 busy           : 1;
U32_FEILD_STOP(vMAC_CSR_CMD)


/**
 * MAC_CSR_DATA Format 5.3.21
 *
 */

/**
 * AFC_CFG Format 5.3.22
 * 31-24 : -
 * 23-16 : Automatic Flow Control HIGH Level
 * 15-8  : Automatic Flow Control LOW Level
 * 7-4   : BackpressureDuration
 * 3     : Flow Control on Multicast Frame
 * 2     : Flow Control on Broadcast Frame
 * 1     : Flow Control on Address Decode
 * 0     : Flow Control on Any Frame
 */
U32_FEILD_START(vAFC_CFG)
uint32 FCANY      : 1;
uint32 FCADD      : 1;
uint32 FCBRD      : 1;
uint32 FCMULT     : 1;
uint32 BACK_DUR   : 4;
uint32 AFC_LO     : 8;
uint32 AFC_HI     : 8;
uint32 useless(0) :8;
U32_FEILD_STOP(vAFC_CFG)


/**
 * E2P_CMD Format 5.3.23
 * 31    : EPC Busy
 * 30-28 : EPC Command
 * 27-10 : -
 * 9     : EPC Timeout
 * 8     : MAC Address Loaded
 * 7-0   : EPC Address
 */
U32_FEILD_START(vE2P_CMD)
uint32 EPC_ADDR     : 8;
uint32 MAC_LOADED   : 1;
uint32 EPC_TIMEOUT  : 1;
uint32 useless(0)   : 18;
uint32 EPC_CMD      : 3;
uint32 EPC_BUSY     : 1;
U32_FEILD_STOP(vE2P_CMD)


/**
 * E2P_DATA Format 5.3.24
 * 31-8  : -
 * 7-0   : EEPROM Data
 */
U32_FEILD_START(vE2P_DATA)
uint32 DATA       : 8;
uint32 useless(0) : 24;
U32_FEILD_STOP(vE2P_DATA)